/**
 * @FileName: ThemesService.java
 * @Author
 * @Description:
 * @Date 2015年12月28日 下午3:26:32
 * @CopyRight ZTE Corporation
 */
package cn.hpclub.server.service;

import java.io.IOException;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.net.MediaType;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;

import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.model.MemberOrg;
import cn.hpclub.server.util.HttpUtil;
import cn.hpclub.server.util.InterfaceUtil;
import cn.hpclub.server.util.QueryHelper;
import cn.hpclub.server.util.SystemConfigUtil;

public class MemberOrgService extends Service {
    public static MemberOrgService service = new MemberOrgService();
    private static final Logger logger = LoggerFactory.getLogger(MemberOrgService.class);
    //private static final String    ESB_HOST_PREFIX = SystemConfigUtil.getSystemConfig().getEsbHostPrefix();
    private static final String REST_HOST_PREFIX = SystemConfigUtil.getSystemConfig().getRestHostPrefix();

    public QueryHelper listQueryHelper(ConcurrentHashMap<String, String> searchInfo) {
        int topId = InterfaceUtil.getIdTop();
        QueryHelper helper = new QueryHelper("select sr.ratify,sr.ratify_time,m.is_lock,m.parent_emp_code,m.enabled as enabled,m.id as id,user_name,m.name,m.member_type, NumCode as org_channel_code,m.emp_code,DisplayName,class_name,IF(orgType.orgIDTmp||orgType2.orgIDTmp2, '是', '否') AS is_accounts_manager",
                "member_org m"
                        + " LEFT JOIN organization org ON m.org_id=org.id"
                        + " LEFT JOIN organization_class org_class ON org.WebsiteId = org_class.id"
                        + " LEFT JOIN (SELECT id AS orgIDTmp FROM `organization` where (parentid=" + topId + " OR parentid IN (select id FROM organization WHERE  parentid=" + topId + "))) AS orgType " + " ON org.id = orgType.orgIDTmp "
                        + " LEFT JOIN (SELECT org.id AS orgIDTmp2, orgcls.WebsiteId AS WebsiteIdType FROM organization org, organization_class orgcls WHERE org.WebsiteId = orgcls.id AND org.enabled=1 AND orgcls.enabled=1 AND ( orgcls.WebsiteId LIKE '6%' OR orgcls.WebsiteId = '1000' OR orgcls.WebsiteId = '4800')) AS orgType2 ON org.id = orgType2.orgIDTmp2"
                        + " LEFT JOIN spreader_register sr ON m.emp_code=sr.emp_code");
        //helper.addCondition("m.org_id=org.id");
        //helper.addCondition("org.WebsiteId = org_class.id");
        helper.addCondition("m.is_deleted=0");

        helper.addCondition(searchInfo.containsKey("username"), "m.user_name like ?", "%" + searchInfo.get("username") + "%");
        helper.addCondition(searchInfo.containsKey("name"), "m.name like ?", "%" + searchInfo.get("name") + "%");
        helper.addCondition(searchInfo.containsKey("empcode"), "m.emp_code like ?", "%" + searchInfo.get("empcode") + "%");
        helper.addCondition(searchInfo.containsKey("orgname"), "org.DisplayName like ?", "%" + searchInfo.get("orgname") + "%");
        helper.addCondition(searchInfo.containsKey("enabled") && ("0".equals(searchInfo.get("enabled")) || "1".equals(searchInfo.get("enabled"))), "m.enabled=" + searchInfo.get("enabled"));
        helper.addCondition(searchInfo.containsKey("starttime"), "m.reg_time >= '" + searchInfo.get("starttime") + " 00:00:00'");
        helper.addCondition(searchInfo.containsKey("endtime"), "m.reg_time <= '" + searchInfo.get("endtime") + " 23:59:59'");
        helper.addCondition(searchInfo.containsKey("isMgr") && ("1".equals(searchInfo.get("isMgr"))), "((orgType.orgIDTmp is not null) or (orgType2.orgIDTmp2 is not null))");
        helper.addCondition(searchInfo.containsKey("isMgr") && ("0".equals(searchInfo.get("isMgr"))), "((orgType.orgIDTmp is  null) and (orgType2.orgIDTmp2 is null))");
        helper.addCondition(searchInfo.containsKey("class_id") && !"0".equals(searchInfo.get("class_id")), "org.WebsiteId=" + searchInfo.get("class_id"));
        helper.addCondition(searchInfo.containsKey("org_id"), "m.org_id in(" + InterfaceUtil.getChlidOrgIdSql(Integer.parseInt(searchInfo.get("org_id")), Constant.MAX_ORG_LEVEL, true) + ")");
        //2017/07/26针对泛店员的改造
        helper.addCondition(searchInfo.containsKey("member_type") && !"-1".equals(searchInfo.get("member_type")), "m.member_type=" + searchInfo.get("member_type"));


        return helper;
    }

    /**
     * 获取查询语句
     */
    @Deprecated//2017/07/26废弃，改用QueryHelper实现
    public String getSqlExceptSelect(ConcurrentHashMap<String, String> searchInfo) {
        int topId = InterfaceUtil.getIdTop();
        String sqlExceptSelect = "FROM member_org , organization_class org_class,organization org"
                + " LEFT JOIN (SELECT id AS orgIDTmp FROM `organization` where (parentid=" + topId
                + " OR parentid IN (select id FROM organization WHERE  parentid=" + topId + "))) AS orgType "
                + " ON org.id = orgType.orgIDTmp "
                + " LEFT JOIN (SELECT org.id AS orgIDTmp2, orgcls.WebsiteId AS WebsiteIdType FROM organization org, organization_class orgcls WHERE org.WebsiteId = orgcls.id AND org.enabled=1 AND orgcls.enabled=1 AND ( orgcls.WebsiteId LIKE '6%' OR orgcls.WebsiteId = '1000' OR orgcls.WebsiteId = '4800')) AS orgType2 ON org.id = orgType2.orgIDTmp2"
                + " where member_org.org_id=org.id and org.WebsiteId = org_class.id and member_org.is_deleted=0  ";

        // 搜索条件加了“所属机构”，隐含了数据限制功能。在账号能看到的机构数下面进行筛选。所以，这里代码屏蔽。
        // sqlExceptSelect += " and member_org.org_id in("
        // + InterfaceUtil.getChlidOrgIdSql(InterfaceUtil.getOrgId(),
        // Constant.MAX_ORG_LEVEL, true) + ") ";

        for (Entry<String, String> item : searchInfo.entrySet()) {
            sqlExceptSelect += buildQuery(item);
        }

        logger.debug("sqlExceptSelect = " + sqlExceptSelect);
        return sqlExceptSelect;
    }

    private String buildQuery(Entry<String, String> item) {
        String sql = "";
        if (item.getKey().equals("username")) {
            sql += " and  member_org.user_name " + " like '%" + item.getValue() + "%'";
        } else if (item.getKey().equals("name")) {
            sql += " and  member_org.name " + " like '%" + item.getValue() + "%'";
        } else if (item.getKey().equals("empcode")) {
            sql += " and  member_org.emp_code " + " like '%" + item.getValue() + "%'";
        } else if (item.getKey().equals("orgname")) {
            sql += " and  DisplayName " + " like '%" + item.getValue() + "%'";
        } else if (item.getKey().equals("enabled")) {
            int memberStatus = Integer.valueOf(item.getValue());
            if ((memberStatus == 0) || (memberStatus == 1)) {
                sql += " and  member_org.enabled " + " = " + memberStatus;
            }
        } else if (item.getKey().equals("starttime")) {
            sql += " and member_org.reg_time >= '" + item.getValue() + " 00:00:00" + "' ";
        } else if (item.getKey().equals("endtime")) {
            sql += " and member_org.reg_time <= '" + item.getValue() + " 23:59:59" + "' ";
        } else if (item.getKey().startsWith("isMgr")) {
            if ("1".equals(item.getValue())) {
                sql += " and ((orgType.orgIDTmp is not null) or (orgType2.orgIDTmp2 is not null)) ";
            } else if ("0".equals(item.getValue())) {
                sql += " and ((orgType.orgIDTmp is  null) and (orgType2.orgIDTmp2 is null)) ";
            }
        } else if (item.getKey().startsWith("class_id")) {
            int classId = Integer.valueOf(item.getValue());
            if (classId != 0) {
                sql += " and org.WebsiteId=" + classId;
            }
        } else if (item.getKey().equals("org_id")) {
            sql += " and member_org.org_id in("
                    + InterfaceUtil.getChlidOrgIdSql(Integer.parseInt(item.getValue()), Constant.MAX_ORG_LEVEL, true)
                    + ") ";
        }
        return sql;
    }

    /**
     * @param cellphone:手机号
     * @Title: searchMemberInfo
     * @Description:从数据库查询工号信息
     */
    public List<Entry<String, Object>> queryMemberInfoInDb(String cellphone) {
        ConcurrentHashMap<String, String> searchMap = new ConcurrentHashMap<String, String>();
        searchMap.put("username", cellphone);
        Record record = Db
                .findFirst("select member_org.enabled as enabled, member_org.id as id,user_name,name,member_type,"
                        + " NumCode as org_channel_code,emp_code,DisplayName,class_name "
                        + MemberOrgService.service.getSqlExceptSelect(searchMap));
        List<Entry<String, Object>> list = new ArrayList<Entry<String, Object>>();
        if (record != null) {
            list.add(createSimpleEntry("user_name", record.getStr("user_name")));
            list.add(createSimpleEntry("name", record.getStr("name")));
            list.add(createSimpleEntry("member_type", record.getInt("member_type") == 1 ? "店长" : "店员"));
            list.add(createSimpleEntry("DisplayName", record.getStr("DisplayName")));
            list.add(createSimpleEntry("emp_code", record.getStr("emp_code")));
        }
        return list;
    }

    private SimpleEntry<String, Object> createSimpleEntry(String key, Object value) {
        return new SimpleEntry<String, Object>(key, value);
    }

    @SuppressWarnings("deprecation")
    private String sendRequest(String uri, String body) throws IOException {
        //String result = HttpUtil.getHttpByPostBody(ESB_HOST_PREFIX + uri, body);//不直接走rpc，而走rest透传接口
        String result = HttpUtil.syncPostJsonBody(REST_HOST_PREFIX + "/business/rpc/esop/rest/" + uri, MediaType.JSON_UTF_8, body, 30000);
        if (HttpUtil.HTTP_ERROR.equals(result)) {
            throw new IOException("网络错误，请稍后再试");
        }
        return result;
    }

    /**
     * @param cellphone:手机号
     * @return List<Entry<String,Object>>
     * @Title: queryEmpCodeInfoFromBOSS
     * @Description:通过ESB接口查询工号信息
     */
    public List<Entry<String, Object>> queryEmpCodeInfoFromBOSS(String cellphone) {
        List<Entry<String, Object>> list = new ArrayList<Entry<String, Object>>();
        try {
            getRegionInfo(cellphone, list);
            getEmpInfo(cellphone, list);
            list.add(createSimpleEntry("bossStatus", 1));
        } catch (IOException e) {
            e.printStackTrace();
            list.clear();
            list.add(createSimpleEntry("bossStatus", 0));
            list.add(createSimpleEntry("bossMsg", "网络错误，请稍后再试"));
        }
        return list;
    }

    private void getEmpInfo(String cellphone, List<Entry<String, Object>> list) throws IOException {
        String result = sendRequest("sGetLogInfoByPhn1", getEmpInfoRequestData(cellphone));
        pareEmpInfoResult(list, result);
    }

    private void pareEmpInfoResult(List<Entry<String, Object>> list, String result) {
        JSONObject data = new JSONObject(result);
        if (isSuccessResult(data)) {
            JSONObject outData = data.getJSONObject("ROOT").getJSONObject("OUT_DATA");
            if (outData.has("LOGINMSG_LIST")) {
                List<Record> empList = new ArrayList<Record>();
                Object loginMsgList = outData.get("LOGINMSG_LIST");
                if (loginMsgList.getClass().equals(JSONArray.class)) {
                    parseEmpInfoAsArray(empList, loginMsgList);
                } else {
                    parseEmpInfoAsObject(empList, loginMsgList);
                }
                list.add(createSimpleEntry("empList", empList));
            }
        }
    }

    /**
     * @param result 返回结果
     *               =======
     *               >>>>>>> 1.7.3-beta
     * @return boolean
     * @Title: isSuccessResult
     * @Description:ESB返回结果是否成功 <<<<<<< HEAD
     */
    private boolean isSuccessResult(JSONObject result) {
        return result.has("ROOT") && result.getJSONObject("ROOT").getInt("RETURN_CODE") == 0
                && (result.getJSONObject("ROOT")).has("OUT_DATA");
    }

    private String getEmpInfoRequestData(String cellphone) {
        JSONObject root = new JSONObject();
        JSONObject body = new JSONObject();
        body.put("PHONE_NO", cellphone);
        root.put("BODY", body);
        return root.toString();
    }

    private void parseEmpInfoAsObject(List<Record> empList, Object loginMsgList) {
        empList.add(getEmpObject((JSONObject) loginMsgList));
    }

    private void parseEmpInfoAsArray(List<Record> empList, Object loginMsgList) {
        JSONArray array = (JSONArray) loginMsgList;
        for (int i = 0; i < array.length(); i++) {
            JSONObject object = array.getJSONObject(i);
            empList.add(getEmpObject(object));
        }
    }

    private Record getEmpObject(JSONObject object) {
        Record record = new Record();
        record.set("LOGIN_NO", object.getString("LOGIN_NO"));
        record.set("LOGIN_NAME", object.getString("LOGIN_NAME"));
        record.set("GROUP_ID", object.getString("GROUP_ID"));
        return record;
    }

    /**
     * @param cellphone 电话号码
     * @throws IOException JSONObject
     * @Title: getRegionInfo
     * @Description:获取归属地信息
     */
    private void getRegionInfo(String cellphone, List<Entry<String, Object>> list) throws IOException {
        String result = sendRequest("sSmsQryScL", getRegionInfoRequestData(cellphone));
        parseRegionInfoResult(list, result);
    }

    private void parseRegionInfoResult(List<Entry<String, Object>> list, String result) {
        JSONObject data = new JSONObject(result);
        if (isSuccessResult(data)) {
            JSONObject outData = data.getJSONObject("ROOT").getJSONObject("OUT_DATA");
            parseReginoName(list, outData);
            parseRegionId(list, outData);
        }
    }

    private void parseRegionId(List<Entry<String, Object>> list, JSONObject outData) {
        if (outData.has("REGION_ID")) {
            int regionId = outData.getInt("REGION_ID");
            list.add(createSimpleEntry("regionId", regionId));
        }
    }

    private void parseReginoName(List<Entry<String, Object>> list, JSONObject outData) {
        if (outData.has("REGION_NAME")) {
            String regionName = outData.getString("REGION_NAME");
            list.add(createSimpleEntry("regionName", regionName));
        }
    }

    private String getRegionInfoRequestData(String cellphone) {
        JSONObject root = new JSONObject();
        JSONObject body = new JSONObject();
        body.put("OLD_SERVER", "");
        body.put("PHONE_NO", cellphone);
        root.put("BODY", body);
        return root.toString();
    }

    /**
     * @param userId:用户id
     * @param userId      >>>>>>> 1.7.3-beta
     * @return boolean:客户经理true,其他false
     * =======
     * @Title: isAccountsManager
     * @Description:根据用户所在机构的类型（渠道类型编码1000、4800、6开头为客户经理;4800判断为SA渠道） 判断是否是客户经理。
     * 联表查询及可获取类型
     * changed by
     * zhouxl in
     * 2016.12.26
     * <<<<<<< HEAD
     */
    public boolean isAccountsManager(String userId) {
        // return isGEManager(userId);//old

        Record member = MemberOrg.dao.isAccountsManager(userId);

        if (null != member) {
            return isMemManager(member);
        }

        return false;
    }

    private boolean isMemManager(Record member) {
        String isAccountsManager = member.getStr("is_accounts_manager");
        return "1".equals(isAccountsManager) ? true : false;
    }

    /**
     * @param userId:用户帐号
     * @return boolean:客户经理true,其他false
     * @Title: isSA
     * @Description:根据用户所在机构的类型（4800判断为SA渠道） 判断是否是SA, 联表查询及可获取类型
     */
    public boolean isSA(String userId) {
        return isGEManager(userId);
    }

    /**
     * @param userId:用户编码 //* @param sqlFilter:查询条件（客户经理和SA查询条件有差异）
     * @return boolean:查询条件是否成立
     * @Title: isGEManager
     * @Description:是否是政企网客户经理
     */
    private boolean isGEManager(String userId) {
        int topOrgId = InterfaceUtil.getIdTop();
        String sql = "SELECT * FROM `organization` where (parentid=? or parentid IN (select id from organization where  parentid=?)) and id in (SELECT org_id FROM member_org WHERE id=?)";
        List<Record> result = Db.find(sql, topOrgId, topOrgId, userId);
        logger.info("result.size=" + result.size());
        if (result.isEmpty()) {
            return false;
        } else {
            return true;
        }
    }

    public String getUserNameByUserId(String userId) {
        return MemberOrg.dao.getUserNameByUserId(userId);
    }
}
